﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Visualizes a time signature.
    /// </summary>
    public partial class TimeSignature : UserControl
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TimeSignature"/> class.
        /// </summary>
        public TimeSignature()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the DataContextChanged event of the UserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (timeSignature != null)
                timeSignature.PropertyChanged -= timeSignature_PropertyChanged;

            timeSignature = DataContext as ViewModel.Elements.CWNotation.TimeSignature;

            if (timeSignature != null)
                timeSignature.PropertyChanged += new PropertyChangedEventHandler(timeSignature_PropertyChanged);

            SetVisualization();
        }

        /// <summary>
        /// Occurs when a property of the visualized time signature has changed.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void timeSignature_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SignatureType")
                SetVisualization();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Sets the visualization.
        /// </summary>
        private void SetVisualization()
        {
            if (timeSignature == null)
            {
                PART_CommonSignature.Visibility = System.Windows.Visibility.Collapsed;
                PART_StandardSignatureN.Visibility = System.Windows.Visibility.Collapsed;
                PART_StandardSignatureD.Visibility = System.Windows.Visibility.Collapsed;
                return;
            }

            switch (timeSignature.SignatureType)
            {
                case Notoric.ViewModel.Elements.TimeSignatureType.Common:
                    PART_StandardSignatureN.Visibility = System.Windows.Visibility.Collapsed;
                    PART_StandardSignatureD.Visibility = System.Windows.Visibility.Collapsed;
                    PART_CommonSignature.Visibility = System.Windows.Visibility.Visible;
                    PART_CommonSignature.Text = "c";
                    break;
                case Notoric.ViewModel.Elements.TimeSignatureType.AllaBreve:
                    PART_StandardSignatureN.Visibility = System.Windows.Visibility.Collapsed;
                    PART_StandardSignatureD.Visibility = System.Windows.Visibility.Collapsed;
                    PART_CommonSignature.Visibility = System.Windows.Visibility.Visible;
                    PART_CommonSignature.Text = "C";
                    break;
                case Notoric.ViewModel.Elements.TimeSignatureType.Standard:
                    PART_StandardSignatureN.Visibility = System.Windows.Visibility.Visible;
                    PART_StandardSignatureD.Visibility = System.Windows.Visibility.Visible;
                    PART_CommonSignature.Visibility = System.Windows.Visibility.Collapsed;
                    break;
            }

            var staffSpaces = timeSignature.FindOwner<ViewModel.Elements.CWNotation.Staff>().Lines.Count - 1;
            var spaceSize = (staffSpaces > 0 ? timeSignature.EffectiveTypeSize / staffSpaces : timeSignature.FindOwner<ViewModel.Elements.CWNotation.Staff>().SpaceSize);

            PART_StandardSignatureN.Margin = new Thickness(0, - 4.5 * spaceSize, 0, 0);
            PART_StandardSignatureD.Margin = new Thickness(0, -2.5 * spaceSize, 0, 0);
            PART_CommonSignature.Margin = new Thickness(0, -3.5 * spaceSize, 0, 0);
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds a reference to the visualized time signature.
        /// </summary>
        private ViewModel.Elements.CWNotation.TimeSignature timeSignature;

        #endregion
    }
}
